package com.dcivision.lucene.highlighter;

import java.io.IOException;
import java.io.StringReader;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.cjk.CJKAnalyzer;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.highlight.Fragmenter;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.Scorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;

import com.dcivision.framework.TextUtility;
import com.dcivision.framework.Utility;

/**
 * highlighte return text.
 * @author sun boy
 *
 */
public class DmsHighlighter {
  
  private List terms = null;
  
  private IndexReader indexReader = null;
  
  private int maxNumFragments = 3;

  private String separator = "...";
  
  
  
  public DmsHighlighter(IndexReader indexReader, List terms) {
    super();
    this.indexReader = indexReader;
    this.terms = terms;
  }

  /**
   * do lucene highlight.
   * @param query
   * @param id
   * @param text
   * @param fieldName
   * @return
   * @throws IOException
   * @
   */
  public String highlight(Query query, int id, String text, String fieldName) throws IOException {
    if (Utility.isEmpty(text) || Utility.isEmpty(this.terms)) return null;
    String summary = null;
    
    Scorer scorer = new QueryScorer(query.rewrite(indexReader), fieldName);
    SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("", "");
    Highlighter highlighter = new Highlighter(formatter, scorer);
    Fragmenter fragmenter = new SimpleFragmenter(100);
    highlighter.setMaxDocBytesToAnalyze(999999999);
    highlighter.setTextFragmenter(fragmenter);
    
    Analyzer analyzer = new CJKAnalyzer();
    TokenStream tokenStream = analyzer.tokenStream(fieldName, new StringReader(text));
    
    //TermPositionVector tpv = (TermPositionVector)indexReader.getTermFreqVector(id, fieldName);
    //TokenStream tokenStream = TokenSources.getTokenStream(tpv);
    summary = highlighter.getBestFragments(tokenStream, text, maxNumFragments, separator);
    return this.format(summary);
  }
  
  /**
   * format string and highlighte.
   * @param summary
   * @return
   * @throws IOException
   */
  private String format(String summary) throws IOException {
    StringBuffer result = new StringBuffer(TextUtility.htmlEncode(summary));
    for (int i=0; i<this.terms.size(); i++) {
      String tmpSummary = result.toString().toLowerCase();
      String keyword = (String)this.terms.get(i);
      int keywordLengh = keyword.length();
      while (true) {
        int startIndex = tmpSummary.lastIndexOf(keyword);
        if (startIndex!=-1) {
          result.insert(startIndex+keywordLengh, "</B>");
          result.insert(startIndex, "<B style='color:#0000ff'>");
          tmpSummary = tmpSummary.substring(0, startIndex);
        }else {
          break;
        }
      }
    }
    return result.toString();
  }

}
